﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;

namespace YArchitech.Revit
{
	public class ElementsUpdater
	{
		public string FailedString { get; set; }

		public ElementsUpdater(Autodesk.Revit.DB.Document doc, List<HYUpdateElementInfo> listNodes)
		{
			this.document = doc;
			this.nodesToUpdate = listNodes;
		}

		protected virtual bool Update(string docTitle)
		{
			bool flag = true;
			new List<HYUpdateElementInfo>();
			Transaction transaction = new Transaction(this.document, "更新数据");
			transaction.Start();
			try
			{
				foreach (HYUpdateElementInfo hyupdateElementInfo in this.nodesToUpdate)
				{
					if (!(hyupdateElementInfo.DocumentTitle == docTitle))
					{
						this.FailedString = "图元所属文档与当前文档不匹配";
						flag = false;
						break;
					}
					Element element = this.document.GetElement(new ElementId(hyupdateElementInfo.ElementID));
					if (element != null && this.CheckCategory(element, BuiltInCategory.OST_PipeCurves))
					{
						flag &= this.UpdatePipe(element, hyupdateElementInfo);
					}
				}
				this.document.Regenerate();
				flag = ((int)transaction.Commit() == 3);
			}
			catch (Exception ex)
			{
				this.FailedString = ex.ToString();
				flag = false;
			}
			finally
			{
				if (transaction != null && transaction.HasStarted() && (int)transaction.GetStatus() != 3)
				{
					transaction.RollBack();
					flag = false;
				}
			}
			return flag;
		}

		public bool UpdateElementInfo()
		{
			string text = this.document.Title;
			if (text.LastIndexOf(".rvt") > 0)
			{
				text = text.Substring(0, text.LastIndexOf(".rvt"));
			}
			bool result;
			if (this.document != null && this.nodesToUpdate != null && this.nodesToUpdate.Count > 0)
			{
				result = this.Update(text);
			}
			else
			{
				this.FailedString = "该数据是链接文件工程的计算结果，与当前文档不符";
				result = false;
			}
			return result;
		}

		protected Connector GetConnectConnector(Connector connector)
		{
			Connector result = null;
			if (connector != null && connector.IsConnected)
			{
				ConnectorSetIterator connectorSetIterator = connector.AllRefs.ForwardIterator();
				while (connectorSetIterator.MoveNext())
				{
					object obj = connectorSetIterator.Current;
					Connector connector2 = obj as Connector;
					if (connector2 != null && connector2.Owner.UniqueId != connector.Owner.UniqueId && ((int)connector2.ConnectorType == 1 || (int)connector2.ConnectorType == 2 || (int)connector2.ConnectorType == 19))
					{
						result = connector2;
						break;
					}
				}
			}
			return result;
		}

		protected ConnectorSet GetConnectors(Element element)
		{
			if (element == null)
			{
				return null;
			}
			FamilyInstance familyInstance = element as FamilyInstance;
			if (familyInstance != null && familyInstance.MEPModel != null)
			{
				return familyInstance.MEPModel.ConnectorManager.Connectors;
			}
			MEPSystem mepsystem = element as MEPSystem;
			if (mepsystem != null)
			{
				return mepsystem.ConnectorManager.Connectors;
			}
			MEPCurve mepcurve = element as MEPCurve;
			if (mepcurve != null)
			{
				return mepcurve.ConnectorManager.Connectors;
			}
			return null;
		}

		protected bool CheckCategory(Element elem, BuiltInCategory buildInCatID)
		{
			if (elem == null)
			{
				return false;
			}
			Category category = elem.Document.Settings.Categories.get_Item(buildInCatID);
			return elem.Category.Id == category.Id;
		}

		protected bool UpdatePipe(Element ele, HYUpdateElementInfo eleInfo)
		{
			bool result = true;
			if (eleInfo.PipeDN > 0)
			{
				Parameter parameter = ele.GetParameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM);
				if (parameter != null)
				{
					parameter.Set((double)eleInfo.PipeDN / 304.8);
				}
				ConnectorSetIterator connectorSetIterator = this.GetConnectors(ele).ForwardIterator();
				while (connectorSetIterator.MoveNext())
				{
					object obj = connectorSetIterator.Current;
					Connector connector = obj as Connector;
					if (connector.IsConnected)
					{
						this.GetConnectConnector(connector).Radius = (double)eleInfo.PipeDN / 304.8 / 2.0;
					}
				}
			}
			return result;
		}

		protected void SetValue(Element elem, BuiltInParameter builtInParam, double valueImperial)
		{
			Parameter parameter = elem.GetParameter(builtInParam);
			if (parameter != null)
			{
				parameter.Set(valueImperial);
			}
		}

		protected void SetDistance(Element elem, BuiltInParameter builtInParam, double value)
		{
			double valueImperial = this.DistanceToStd(value);
			this.SetValue(elem, builtInParam, valueImperial);
		}

		protected double GetValue(Element elem, BuiltInParameter builtInParam)
		{
			Parameter parameter = elem.GetParameter(builtInParam);
			if (parameter == null)
			{
				return 0.0;
			}
			return parameter.AsDouble();
		}

		protected double DistanceToStd(double meters)
		{
			return UnitConvert.CovertToAPI(meters, (Autodesk.Revit.DB.DisplayUnitType)0);
		}

		protected ConnectorManager GetElementConnectorManager(Element element)
		{
			ConnectorManager connectorManager;
			if (element is FamilyInstance)
			{
				connectorManager = (element as FamilyInstance).MEPModel.ConnectorManager;
			}
			else
			{
				connectorManager = (element as MEPCurve).ConnectorManager;
			}
			return connectorManager;
		}

		protected List<Connector> GetElementConnectors(Element element)
		{
			ConnectorManager elementConnectorManager = this.GetElementConnectorManager(element);
			if (elementConnectorManager == null)
			{
				return null;
			}
			List<Connector> list = new List<Connector>();
			foreach (object obj in elementConnectorManager.Connectors)
			{
				Connector connector = (Connector)obj;
                if ((int)connector.Domain == 3 || connector.Domain == (Autodesk.Revit.DB.Domain)1)
				{
					list.Add(connector);
				}
			}
			return list;
		}

		protected List<HYUpdateElementInfo> nodesToUpdate;

		protected Document document;
	}
}
